package cn.liyunqi.ttv.main.controller;

import cn.liyunqi.core.exception.BizException;
import cn.liyunqi.core.util.UUIDUtil;
import cn.liyunqi.ttv.main.action.TTVActionUtil;
import cn.liyunqi.ttv.main.constant.ChangeCompany;
import cn.liyunqi.ttv.main.constant.Constants;
import cn.liyunqi.ttv.main.constant.VoiceType;
import cn.liyunqi.ttv.main.localdb.ConfigHelper;
import cn.liyunqi.ttv.main.util.FileUtil;
import cn.liyunqi.ttv.main.util.PCMToWave;
import cn.liyunqi.ttv.main.util.StringUtil;
import cn.liyunqi.ttv.main.util.TimeUtil;
import cn.liyunqi.ttv.main.view.AlertUtil;
import cn.liyunqi.ttv.main.vo.UserPreference;
import cn.liyunqi.ttv.main.vo.UserTextHistory;
import com.alibaba.fastjson.JSONObject;
import com.baidu.aip.speech.AipSpeech;
import com.baidu.aip.speech.TtsResponse;

import com.github.nobodxbodon.zhconverter.简繁转换类;

import com.iflytek.cloud.speech.*;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.InputEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import org.apdplat.word.WordSegmenter;
import org.apdplat.word.segmentation.SegmentationAlgorithm;
import org.apdplat.word.segmentation.Word;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
import org.jaudiotagger.audio.mp3.MP3File;
import org.jaudiotagger.audio.wav.WavFileReader;
import org.jaudiotagger.audio.wav.util.WavInfoReader;

import java.awt.*;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;

import java.util.*;
import java.util.List;
import java.util.function.BiConsumer;


public class MainUIController extends BaseFXController {

    @FXML
    private Button begianCreateBtn;

    @FXML
    private Button filePathBtn;

    @FXML
    private Label filePathLab;

    @FXML
    private TextField fileNameTxt;

    @FXML
    private ScrollBar spdScroll;

    @FXML
    private ScrollBar pitScroll;

    @FXML
    private ScrollBar volScroll;

    @FXML
    private Label spdLab;

    @FXML
    private Label pitLab;

    @FXML
    private Label volLab;

    @FXML
    private ProgressBar progressBar;

    @FXML
    private TextArea setTextTxt;

    @FXML
    private ComboBox perSel;

    @FXML
    private Label wenhaoImg;

    @FXML
    private Label userMailLab;
    @FXML
    private Label limitDateLab;

    @FXML
    private CheckBox simplifiedChk;

    @FXML
    private CheckBox traditionalChk;

    //充值
    @FXML
    private Button rechargeBtn;

    //设置
    @FXML
    private Button setUpBtn;

    @FXML
    private Button cleanHistoryBtn;

    @FXML
    private ScrollPane historyScrollPane;

    @FXML
    private Label fontCountLab;

    @FXML
    private Button begianFindImgBtn;

    private String textId = null;

    private Map<String,Button> lookMap = new HashMap<>();

    private Map<String,Button> delMap = new HashMap<>();

    private static String R = System.getProperty("line.separator");

    private static final Integer SCORLL_MIN = 0;
    private static final Integer SCORLL_MAX = 100;

    private static final Integer SCORLL_DEFAULT = 50;

    //设置APPID/AK/SK
    public static String Baidu_APP_ID = null;
    public static String Baidu_API_KEY = null;
    public static String Baidu_SECRET_KEY = null;

    public static String Kedaxunfei_APP_ID = null;
    private List<List<Word>> segmentationList;

    private void disableHandle(boolean flg){
        begianCreateBtn.setDisable(flg);
        begianFindImgBtn.setDisable(flg);
        setTextTxt.setDisable(flg);
        setTextTxt.setDisable(flg);
        filePathBtn.setDisable(flg);
        fileNameTxt.setDisable(flg);
        spdScroll.setDisable(flg);
        pitScroll.setDisable(flg);
        volScroll.setDisable(flg);

        rechargeBtn.setDisable(flg);
        setUpBtn.setDisable(flg);
        cleanHistoryBtn.setDisable(flg);

        simplifiedChk.setDisable(flg);
        traditionalChk.setDisable(flg);

        perSel.setDisable(flg);

        lookMap.forEach(new BiConsumer<String, Button>() {
            @Override
            public void accept(String s, Button button) {
                button.setDisable(flg);
            }
        });
        delMap.forEach(new BiConsumer<String, Button>() {
            @Override
            public void accept(String s, Button button) {
                button.setDisable(flg);
            }
        });

    }
    private void updateViewUserPreference(UserPreference userPreference){

        if(userPreference == null){
            userPreference = new UserPreference();
        }
        //保存路径
        if(!StringUtil.isNullOrEmpty(userPreference.getFilePath())){
            File file = new File(userPreference.getFilePath());
            if(file.exists()){
                filePathLab.setText(userPreference.getFilePath());
            }
        }

        //文件名
        if(!StringUtil.isNullOrEmpty(userPreference.getFileName()))
            fileNameTxt.setText(userPreference.getFileName());

        //spd	String	语速，取值0-9，默认为5中语速	否
        //语速
        if(userPreference.getSpd() != null && SCORLL_MIN <= userPreference.getSpd() && SCORLL_MAX >= userPreference.getSpd()){
            spdScroll.setValue(userPreference.getSpd());
            spdLab.setText(userPreference.getSpd() + "");
        }else{
            spdScroll.setValue(SCORLL_DEFAULT );
            spdLab.setText(SCORLL_DEFAULT + "");
        }

        //pit	String	音调，取值0-9，默认为5中语调	否
        //音调
        if(userPreference.getPit() != null && SCORLL_MIN <= userPreference.getPit() && SCORLL_MAX >= userPreference.getPit()){
            pitScroll.setValue(userPreference.getPit());
            pitLab.setText(userPreference.getPit() + "");
        }else{
            pitScroll.setValue(SCORLL_DEFAULT );
            pitLab.setText(SCORLL_DEFAULT + "");
        }

        //vol	String	音量，取值0-15，默认为5中音量	否
        //音量
        if(userPreference.getVol() != null && SCORLL_MIN <= userPreference.getVol() && SCORLL_MAX >= userPreference.getVol()){
            volScroll.setValue(userPreference.getVol());
            volLab.setText(userPreference.getVol() + "");
        }else{
            volScroll.setValue(SCORLL_DEFAULT );
            volLab.setText(SCORLL_DEFAULT + "");
        }

        //发音人
        if(!StringUtil.isNullOrEmpty(userPreference.getPerId())){
            VoiceType type = VoiceType.getVoiceTypeById(userPreference.getPerId());
            if(type != null){
                perSel.setValue(type);
            }
        }
        //字幕简体繁体
        simplifiedChk.setSelected(userPreference.getSimplifiedFlg() == null?false:1 == userPreference.getSimplifiedFlg());
        traditionalChk.setSelected(userPreference.getTraditionalFlg() == null?true:1 == userPreference.getTraditionalFlg());

    }
    public void getApiParam(){
        if(Baidu_APP_ID == null || Baidu_API_KEY == null || Baidu_SECRET_KEY == null){
            JSONObject json = TTVActionUtil.getApiParam();
            if(json != null){
                Baidu_APP_ID = json.getString("Baidu_APP_ID");
                Baidu_API_KEY = json.getString("Baidu_API_KEY");
                Baidu_SECRET_KEY = json.getString("Baidu_SECRET_KEY");
                Kedaxunfei_APP_ID = json.getString("Kedaxunfei_APP_ID");
            }
        }
    }

    private void renderHistory(List<UserTextHistory> list){
        VBox pane = new VBox();
        pane.setSpacing(8);
        pane.setPadding(new Insets(5,0,5,0));

        pane.setPrefWidth(255);


        for (int i = 0; i < list.size(); i++) {

            VBox temp = getCellVbox(list.get(i));

            pane.getChildren().add(temp);
            //pane.getChildren().add();
        }

        historyScrollPane.setContent(pane);

    }

    private VBox getCellVbox(UserTextHistory history){
        VBox temp = new VBox();

        temp.setId(history.getTextId());
        //temp.setPrefWidth(historyScrollPane.getPrefViewportWidth());
        temp.setSpacing(4);
        temp.setPadding(new Insets(0,0,0,10));

        Label sim = new Label();
        sim.setText(history.getTextSimValue());
        temp.getChildren().add(sim);

        Label createDateLab = new Label();
        createDateLab.setText("转换时间  " + history.getCreateDate());
        temp.getChildren().add(createDateLab);

        HBox buttonBox = new HBox();
        buttonBox.setSpacing(10);
        temp.getChildren().add(buttonBox);
        buttonBox.setAlignment(Pos.CENTER_RIGHT);

        //style="-fx-background-color: #87CECB;"
        Button lookBtn = new Button();
        lookBtn.setText("立即查看");
        lookBtn.setStyle("-fx-background-color: #CECEFF;");
        lookBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                UserTextHistory detail = ConfigHelper.getTextHistoryByTextId(history.getTextId());
                textId = history.getTextId();
                if(detail != null){
                    setTextTxt.setText(detail.getTextValue());
                    updateViewUserPreference(detail);
                    getFontCount();
                }
            }
        });

        buttonBox.getChildren().add(lookBtn);
        lookMap.put(history.getTextId(),lookBtn);

        Button delBtn = new Button();
        delBtn.setText("删除");
        delBtn.setStyle("-fx-background-color: #D9B3B3;");
        delBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                delMap.remove(history.getTextId());
                lookMap.remove(history.getTextId());
                textId = null;
                ObservableList<Node>tempList = ((VBox) historyScrollPane.getContent()).getChildren();
                for (int i = 0; i < tempList.size(); i++) {
                    if(history.getTextId().equals(tempList.get(i).getId())){
                        tempList.remove(tempList.get(i));
                    }
                }
            }
        });
        buttonBox.getChildren().add(delBtn);
        delMap.put(history.getTextId(),delBtn);

        //虚线
        Separator line = new Separator();
        temp.getChildren().add(line);
        return temp;
    }

    public void initialize(URL location, ResourceBundle resources) {

        //获取API参数
        try {
            getApiParam();
        }catch (BizException biz){

        }

        //基础数据绑定与设值
        ObservableList<VoiceType> voiceTypeList  = FXCollections.observableArrayList();
        voiceTypeList.setAll(VoiceType.valuesForSystem());

        perSel.setItems(voiceTypeList);

        //重写tostring方法
        perSel.converterProperty().set(new StringConverter<VoiceType>() {
            @Override
            public String toString(VoiceType object) {
                return object.getName();
            }

            @Override
            public VoiceType fromString(String string) {
                return null;
            }
        });

        spdScroll.addEventHandler(InputEvent.ANY, new ScrollChangeHandler(spdLab,spdScroll));
        pitScroll.addEventHandler(InputEvent.ANY, new ScrollChangeHandler(pitLab,pitScroll));
        volScroll.addEventHandler(InputEvent.ANY, new ScrollChangeHandler(volLab,volScroll));

        progressBar.setProgress(0);
        wenhaoImg.setTooltip(new Tooltip("1、 语言为中英文的发音人可以支持中英文的混合朗读。 \n2、 英文发音人只能朗读英文，中文无法朗读。 \n3、 汉语发音人只能朗读中文，遇到英文会以单个字母的方式进行朗读"));

        //获取用户信息
        userMailLab.setText(Constants.mail);
        if(Constants.limitTime != null && Constants.limitTime > 0){
            limitDateLab.setText(TimeUtil.formatToStringDate(Constants.limitTime));
        }else{
            limitDateLab.setText("非会员");
        }
        //获取历史操作记录
        List<UserTextHistory> list = ConfigHelper.getTextHistoryByUserId(Constants.userId);
        renderHistory(list);

        //获取用户偏好
        UserPreference userPreference = ConfigHelper.getUserPreferenceByUserId(Constants.userId);
        updateViewUserPreference(userPreference);

        MainUIController that = this;
        //设置与充值绑定
        setUpBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                SetUpUIController controller = (SetUpUIController) loadFXMLPage("设置", FXMLPage.SetUp, false);
                controller.setMainUIController(that);
                controller.showDialogStage();
            }
        });
        /*.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                SetUpUIController controller = (SetUpUIController) loadFXMLPage("会员充值", FXMLPage.SetUp, false);
                controller.setMainUIController(that);
                controller.showDialogStage();
            }
        });
        */


    }

    private class ScrollChangeHandler implements EventHandler<Event>{
        private Label label;
        private ScrollBar bar;
        ScrollChangeHandler(Label label ,ScrollBar bar){
            super();
            this.label = label;
            this.bar = bar;
        }

        @Override
        public void handle(Event evt) {
            double value = bar.getValue();
            label.setText(((int) value) + "");
        }
    }

    public Task createWorker(String text, String path, String fileName, int spd, int pit, int vol, VoiceType per, boolean simplifiedflg, boolean traditionalflg) {


        return new Task() {

            public static final int LENGTH = 512;

            @Override
            protected Object call() {

                try {

                    getApiParam();
                    checkAuth();

                    disableHandle(true);


                    if(per.getType().equals(ChangeCompany.Baidu)){
                        baiduChange( text,  path,  fileName,  spd,  pit,  vol,  per,  simplifiedflg,  traditionalflg);
                    }else{
                        kedaxunfeiChange( text,  path,  fileName,  spd,  pit,  vol,  per,  simplifiedflg,  traditionalflg);
                    }
                }catch (BizException biz){
                    AlertUtil.showErrorAlert(biz.getMessage());
                }catch (Exception ex){
                    ex.printStackTrace();
                    System.out.println(ex);
                    AlertUtil.showErrorAlert("转化失败");
                }finally {
                    //由于科大讯飞的异步加载因此不在finally里面控制
                    if(per.getType().equals(ChangeCompany.Baidu)){
                        disableHandle(false);
                    }
                }

                return true;
            }

            /**
             * 百度转换
             * @param text
             * @param path
             * @param fileName
             * @param spd
             * @param pit
             * @param vol
             * @param per
             * @param simplifiedflg
             * @param traditionalflg
             */
            private void baiduChange(String text, String path, String fileName, int spd, int pit, int vol, VoiceType per, boolean simplifiedflg, boolean traditionalflg) throws IOException {
                //FileWriter srtfw = null;
                BufferedWriter srtbw = null;
                OutputStream srtos = null;
                OutputStreamWriter srtosw = null;

                try {

                    //先将文本备份
                    String temp = new String(text);

                    BigDecimal textLen = new BigDecimal(temp.length());

                    String srtfileName = fileName.substring(0,fileName.length() - 4 ) + ".srt";

                    //字幕文件处理
                    File srtfile = new File(path + "/" + srtfileName);
                    if(!FileUtil.fileIsExists(path + "/" + srtfileName)){
                        srtfile.createNewFile();
                    }

                    if(srtos == null) {
                        srtos = new FileOutputStream(srtfile);
                        srtos.write(new byte[]{(byte)0xEF, (byte)0xBB, (byte)0xBF});
                    }
                    //如果是覆盖的情况而且还没有入签名

                    srtosw = new OutputStreamWriter(srtos, "UTF-8");

                    srtbw = new BufferedWriter(srtosw);

                    Integer srtrowNum = 0;
                    //如果追加的情况下获取最后第四行的行号

                    // 初始化一个AipSpeech
                    AipSpeech client = new AipSpeech(Baidu_APP_ID, Baidu_API_KEY, Baidu_SECRET_KEY);
                    // 可选：设置网络连接参数
                    client.setConnectionTimeoutInMillis(2000);
                    client.setSocketTimeoutInMillis(60000);

                    // 可选：设置代理服务器地址, http和socket二选一，或者均不设置
                    //client.setHttpProxy("proxy_host", proxy_port);  // 设置http代理
                    //client.setSocketProxy("proxy_host", proxy_port);  // 设置socket代理

                    // 可选：设置log4j日志输出格式，若不设置，则使用默认配置
                    // 也可以直接通过jvm启动参数设置此环境变量
                    //System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");

                    HashMap<String, Object> options = new HashMap<String, Object>();
                    //spd	String	语速，取值0-9，默认为5中语速	否
                    //pit	String	音调，取值0-9，默认为5中语调	否
                    //vol	String	音量，取值0-15，默认为5中音量
                    int tempspd = spd/10 > 9?9:spd/10;
                    int temppit = pit/10 > 9? 9:pit/10;
                    int tempvol = vol/10;
                    options.put("spd", tempspd + "");
                    options.put("pit", temppit + "");
                    options.put("vol", tempvol + "");
                    options.put("per", per.getValue() + "");//发音人选择, 0为女声，1为男声，3为情感合成-度逍遥，4为情感合成-度丫丫，默认为普通女

                    //第一次覆盖
                    boolean appendFlg = false;

                    //将文本切分
                    while (temp.length() > 0) {
                        //合成文本长度必须小于1024字节，如果本文长度较长，可以采用多次请求的方式。文本长度不可超过限制
                        String createValue = temp.substring(0, temp.length() < LENGTH ? temp.length() : LENGTH);
                        //找到最大程度内的符号
                        int index = 0;
                        int eDouhao = createValue.lastIndexOf(",");
                        int eJuhao = createValue.lastIndexOf(".");
                        int eWenhao = createValue.lastIndexOf("?");
                        int eGantan = createValue.lastIndexOf("!");
                        int cDouhao = createValue.lastIndexOf("，");
                        int cJuhao = createValue.lastIndexOf("。");
                        int cWenhao = createValue.lastIndexOf("？");
                        int cGantan = createValue.lastIndexOf("！");

                        if(eDouhao > index){
                            index = eDouhao;
                        }
                        if(eJuhao > index){
                            index = eJuhao;
                        }
                        if(cDouhao > index){
                            index = cDouhao;
                        }
                        if(cJuhao > index){
                            index = cJuhao;
                        }
                        if(eWenhao > index){
                            index = eWenhao;
                        }
                        if(eGantan > index){
                            index = eGantan;
                        }
                        if(cWenhao > index){
                            index = cJuhao;
                        }
                        if(cGantan > index){
                            index = cJuhao;
                        }
                        if(index <= 0){
                            index = createValue.length();
                        }
                        createValue = temp.substring(0, index);
                        temp = temp.substring(index);

                        // 调用接口
                        TtsResponse res = client.synthesis(createValue, "zh", 1, options);
                        byte[] data = res.getData();
                        org.json.JSONObject res1 = res.getResult();
                        if (data != null) {
                            DataOutputStream out = null;

                            double mp3LenOld = 0;
                            //获取上一次音频文件的时长
                            if(FileUtil.fileIsExists(path + "/" + fileName) && appendFlg){
                                File file = new File(path + "/" + fileName);
                                MP3File f = (MP3File)AudioFileIO.read(file);
                                MP3AudioHeader audioHeader = (MP3AudioHeader)f.getAudioHeader();
                                mp3LenOld = audioHeader.getPreciseTrackLength();
                            }


                            try {
                                //追加的方式

                                out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(path + "/" + fileName, appendFlg)));
                                out.write(data);
                            } catch (Exception e) {
                                e.printStackTrace();
                            } finally {
                                if (out != null) {
                                    try {
                                        out.close();
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                }

                                //获取写入后的时长
                                if(FileUtil.fileIsExists(path + "/" + fileName)){
                                    File file = new File(path + "/" + fileName);
                                    MP3File f = (MP3File)AudioFileIO.read(file);
                                    MP3AudioHeader audioHeader = (MP3AudioHeader)f.getAudioHeader();
                                    double mp3LenNew = audioHeader.getPreciseTrackLength();

                                    //备份字幕使用
                                    createValue = createValue.replaceAll(" ","");
                                    createValue = createValue.replaceAll("　","");

                                    createValue = StringUtil.replaceBlank(createValue);

                                    srtrowNum = writeTextInSrt(mp3LenOld,mp3LenNew,createValue,srtbw,srtrowNum,simplifiedflg,traditionalflg);

                                }

                                appendFlg = true;

                                //Thread.sleep(2000);
                                updateMessage("2000 milliseconds");
                                //计算滚动条
                                BigDecimal tempLen = new BigDecimal(temp.length());

                                updateProgress(new BigDecimal(1000).subtract(tempLen.divide(textLen, 5, BigDecimal.ROUND_HALF_DOWN).multiply(new BigDecimal(1000))).longValue(), 1000);

                            }
                        }
                        if (res1 != null) {
                            System.out.println(res1.toString(2));

                            //500	不支持的输入
                            //501	输入参数不正确
                            //502	token验证失败
                            //503	合成后端错误
                            String errNo = res1.get("err_no").toString();
                            if (errNo != null) {
                                switch (errNo) {
                                    case "500":
                                        throw new BizException("转换失败：不支持的输入");
                                    case "501":
                                        throw new BizException("转换失败：输入参数不正确");
                                    case "502":
                                        throw new BizException("转换失败：token验证失败");
                                    case "503":
                                        throw new BizException("转换失败：合成后端错误");
                                }
                            }
                        }
                    }

                    AlertUtil.showInfoAlert("转化成功");
                    updateInHistory( text, path, fileName, spd, pit, vol, per, simplifiedflg, traditionalflg);
                    updateProgress(1000, 1000);

                }catch (BizException biz){
                    AlertUtil.showErrorAlert(biz.getMessage());
                }catch (Exception ex){
                    ex.printStackTrace();
                    System.out.println(ex);
                    AlertUtil.showErrorAlert("转化失败");
                }finally {
                    if(srtbw != null){
                        srtbw.flush();
                        srtbw.close();
                    }
                    if(srtosw != null){
                        //srtosw.flush();
                        srtosw.close();
                    }
                    if(srtos != null){
                        srtos.close();
                    }
                }
            }

            /**
             * 科大讯飞转换
             * @param text
             * @param path
             * @param fileName
             * @param spd
             * @param pit
             * @param vol
             * @param per
             * @param simplifiedflg
             * @param traditionalflg
             */
            private void kedaxunfeiChange(String text, String path, String fileName, int spd, int pit, int vol, VoiceType per, boolean simplifiedflg, boolean traditionalflg) {

                //PCM临时文件夹
                String fileTempFileName = UUIDUtil.getUUID();
                String fileTempPath = "PCMTEMP";
                File file = new File(fileTempPath);
                if (!file.exists()) {
                    file.mkdir();
                }

                SynthesizeToUriListener mSynListener = new SynthesizeToUriListener(){

                    //progress为合成进度0~100
                    @Override
                    public void onBufferProgress(int i) {
                        updateProgress(i * 8, 1000);
                    }
                    //会话合成完成回调接口
                    //uri为合成保存地址，error为错误信息，为null时表示合成会话成功
                    @Override
                    public void onSynthesizeCompleted(String s, SpeechError speechError) {
                        if(speechError == null){

                            FileOutputStream srtos = null;
                            OutputStreamWriter srtosw = null;
                            BufferedWriter srtbw = null;

                            String wavPath = "./" + fileTempPath + "/" + fileTempFileName + ".wav";
                            try {
                                String textTemp = new String(text);
                                //先将PCM转化成WAV
                                PCMToWave.convertAudioFiles(s,wavPath);

                                if(FileUtil.fileIsExists(wavPath)){

                                    File wavfile = new File(wavPath);

                                    Encoder encoder = new Encoder();
                                    MultimediaInfo m = encoder.getInfo(wavfile);
                                    double mp3LenNew = m.getDuration()/1000.0;

                                    //再将WAV转化成MP3
                                    PCMToWave.execute(wavfile,path + "/" + fileName);

                                    //File file = new File(path + "/" + fileName);
                                    //MP3File f = (MP3File)AudioFileIO.read(file);
                                    //MP3AudioHeader audioHeader = (MP3AudioHeader)f.getAudioHeader();
                                    //double mp3LenNew = audioHeader.getPreciseTrackLength();

                                    String srtfileName = fileName.substring(0,fileName.length() - 4 ) + ".srt";

                                    //字幕文件处理
                                    File srtfile = new File(path + "/" + srtfileName);

                                    if(!FileUtil.fileIsExists(path + "/" + srtfileName)){
                                        srtfile.createNewFile();
                                    }

                                    if(srtos == null) {
                                        srtos = new FileOutputStream(srtfile);
                                        srtos.write(new byte[]{(byte)0xEF, (byte)0xBB, (byte)0xBF});
                                    }
                                    //如果是覆盖的情况而且还没有入签名

                                    srtosw = new OutputStreamWriter(srtos, "UTF-8");

                                    srtbw = new BufferedWriter(srtosw);

                                    //备份字幕使用
                                    textTemp = textTemp.replaceAll(" ","");
                                    textTemp = textTemp.replaceAll("　","");

                                    textTemp = StringUtil.replaceBlank(textTemp);

                                    writeTextInSrt(0,mp3LenNew,textTemp,srtbw,0,simplifiedflg,traditionalflg);

                                }

                                updateProgress(1000, 1000);
                                AlertUtil.showInfoAlert("转化成功");
                                updateInHistory( text, path, fileName, spd, pit, vol, per, simplifiedflg, traditionalflg);
                            } catch (Exception e) {
                                e.printStackTrace();
                                AlertUtil.showErrorAlert("转化失败");
                            }finally {
                                try{
                                    if(srtbw != null){
                                        srtbw.flush();
                                        srtbw.close();
                                    }
                                    if(srtosw != null){
                                        //srtosw.flush();
                                        srtosw.close();
                                    }
                                    if(srtos != null){
                                        srtos.close();
                                    }
                                }catch (Exception ex){

                                }
                                //删除临时文件
                                File tempFile = new File(s);
                                if(FileUtil.fileIsExists(tempFile)){
                                    tempFile.delete();
                                    tempFile = null;
                                }
                                File tempwavFile = new File(wavPath);
                                if(FileUtil.fileIsExists(tempwavFile)){
                                    tempwavFile.delete();
                                }
                                updateProgress(1000, 1000);
                                disableHandle(false);
                            }

                        }else{
                            disableHandle(false);
                            AlertUtil.showErrorAlert("转化失败");
                        }
                    }

                    @Override
                    public void onEvent(int i, int i1, int i2, int i3, Object o, Object o1) {
                        System.out.println(i);
                        System.out.println(i1);
                        System.out.println(i2);
                        System.out.println(i3);
                        System.out.println(o);
                        System.out.println(o1);
                    }
                };

                //1.创建 SpeechSynthesizer 对象
                StringBuffer param = new StringBuffer();
                param.append( "appid=" + Kedaxunfei_APP_ID);
                SpeechUtility.createUtility( param.toString() );
                SpeechSynthesizer mTts= SpeechSynthesizer.createSynthesizer( );
                //2.合成参数设置，详见《MSC Reference Manual》SpeechSynthesizer 类
                mTts.setParameter(SpeechConstant.VOICE_NAME, per.getValue());//设置发音人
                mTts.setParameter(SpeechConstant.SPEED, spd + "");//设置语速
                mTts.setParameter(SpeechConstant.VOLUME, vol + "");//设置音量，范围 0~100
                mTts.setParameter(SpeechConstant.PITCH, pit + "");//设置语调，范围0~100

                //3.开始合成
                //无声
                mTts.synthesizeToUri(text, "./" + fileTempPath + "/" + fileTempFileName + ".pcm",mSynListener);


            }

            /**
             *
             * @param beginTime 开始时间
             * @param endTime 结束时间
             * @param value 转变值
             * @param srtbw 写入流
             * @param srtrowNum 行号
             * @param simplifiedflg 简体标记
             * @param traditionalflg 繁体标记
             * @return
             * @throws IOException
             */
            private int writeTextInSrt(double beginTime, double endTime, String value, BufferedWriter srtbw, int srtrowNum, boolean simplifiedflg, boolean traditionalflg) throws IOException {

                Integer min = 5;
                Integer max = 17;
                Integer defaultIndex = 10;

                //保存文档（已经将不需要的空格换行去除了）
                String temp = new String(value);

                //将不需要的字符去除。
                temp = temp.replaceAll(",","  ")//逗号 影响
                        .replaceAll("，","  ")//逗号 影响
                        .replaceAll("\\.","  ")//句号 影响
                        .replaceAll("。","  ")//句号 影响
                        .replaceAll("\\!","  ")//感叹号 影响
                        .replaceAll("！","  ")//感叹号 影响
                        .replaceAll("\\?","  ")//问号 影响
                        .replaceAll("？","  ")//问号 影响
                        .replaceAll("\\:","  ")
                        .replaceAll("："," ")
                        .replaceAll("“","")
                        .replaceAll("”","")
                        .replaceAll("\"","")
                        .replaceAll("-","")
                        .replaceAll("—","")
                        .replaceAll("\\(","")
                        .replaceAll("\\)","")
                        .replaceAll("《","")
                        .replaceAll("》","")
                        .replaceAll("（","")
                        .replaceAll("）","")
                        .replaceAll("<","")
                        .replaceAll(">","")
                        .replaceAll("、","  ")
                        .replaceAll("；","  ")
                        .replaceAll(";","  ");


                //获取实际文字长度（已经将不需要的空格换行去除了）
                //String tempLen = new String(value);

                //tempLen = formatClearValue(tempLen);
                //获取每一个字的大致时间
                double everyFont = (endTime - beginTime)/temp.length();

                System.out.println("====" + value);

                while (temp.trim().length() > 0){

                    int index = 0;

                    if(temp.startsWith(",")){
                        int del = temp.indexOf(",");
                        if(temp.length() > 1){
                            temp = temp.substring(del + 1);
                        }else{
                            break;
                        }
                    }

                    if(max >= temp.length()){
                        index = temp.length();
                    }else{
                        String everyTemp = temp.substring(0,max);
                        index = everyTemp.lastIndexOf(" ");
                        if(index < min){
                            index = defaultIndex;
                        }
                    }

                    //在还没剪切前获取开始时间
                    double tempStartTime = endTime - everyFont * temp.length();
                    String writeValueTemp = temp.substring(0,index);

                    temp = temp.substring(index);
                    double tempEndTime = endTime - everyFont * temp.length();

                    if(writeValueTemp == null || writeValueTemp.trim().isEmpty()){
                        continue;
                    }
                    writeValueTemp = writeValueTemp.trim();
                    writeValueTemp = writeValueTemp.replace("  "," ");
                    String writeValue = "";
                    if(simplifiedflg){
                        writeValue = com.github.nobodxbodon.zhconverter.简繁转换类.转换(writeValueTemp, 简繁转换类.目标.简体);
                    }
                    if(simplifiedflg && traditionalflg){
                        writeValue = writeValue + R;
                    }
                    if(traditionalflg){
                        writeValue = writeValue + com.github.nobodxbodon.zhconverter.简繁转换类.转换(writeValueTemp, 简繁转换类.目标.繁体);
                    }

                    //font size
                    srtrowNum = srtrowNum + 1;
                    srtbw.write(srtrowNum + R);//行号
                    srtbw.write(TimeUtil.fotmatDoubleToHMS(tempStartTime > 0.12 ? tempStartTime - 0.12:tempStartTime+0.01) + " --> " + TimeUtil.fotmatDoubleToHMS(tempEndTime > 0.13?tempEndTime - 0.13:tempEndTime) + R);//时间
                    srtbw.write(writeValue + R);//字幕
                    srtbw.write( R);//空行

                    System.out.println("组装成的字符串====" + writeValue);

                }
                return srtrowNum;
            }

        };
    }




    @FXML
    public void begianCreateHandle() {

        String path = filePathLab.getText();
        if(path == null || path.trim().isEmpty()){
            AlertUtil.showErrorAlert("请选择存放目录");
            return;
        }
        path = path.trim();
        String fileName = fileNameTxt.getText();
        if(fileName == null || fileName.trim().isEmpty()){
            AlertUtil.showErrorAlert("请填写保存文件名");
            return;
        }
        fileName = fileName.trim();

        if(!fileName.toLowerCase().endsWith(".mp3")){
            fileName = fileName + ".mp3";
        }

        //是否覆盖

        //判断文件是否存在
        if(!FileUtil.fileIsExists(path + "/" + fileName)){
            //开启线程启动滚动条
            createVoice();

        }else{
            AlertAskController controller = (AlertAskController) loadFXMLPage("文件提醒", FXMLPage.AlertAsk, false);
            controller.setMainUIController(this);
            controller.showDialogStage();
        }

    }

    public void createVoice(){

        String text = setTextTxt.getText();
        if(text == null || text.trim().isEmpty()){
            AlertUtil.showErrorAlert("请输入转化文本");
            return;
        }
        text = text.trim();
        String path = filePathLab.getText();
        if(path == null || path.trim().isEmpty()){
            AlertUtil.showErrorAlert("请选择存放目录");
            return;
        }
        path = path.trim();
        String fileName = fileNameTxt.getText();
        if(fileName == null || fileName.trim().isEmpty()){
            AlertUtil.showErrorAlert("请填写保存文件名");
            return;
        }
        fileName = fileName.trim();

        if(!fileName.endsWith(".mp3")){
            fileName = fileName + ".mp3";
        }

        int spd  = (int) spdScroll.getValue();
        int pit  = (int) pitScroll.getValue();
        int vol  = (int) volScroll.getValue();

        SingleSelectionModel per = perSel.getSelectionModel();

        VoiceType type = (VoiceType)per.getSelectedItem();
        if(type == null){
            AlertUtil.showErrorAlert("请选择发音人");
            return;
        }
        boolean simplifiedflg = simplifiedChk.isSelected();
        boolean traditionalflg = traditionalChk.isSelected();
        if((!simplifiedflg) && (!traditionalflg)){
            AlertUtil.showErrorAlert("字母类型必须选择一项");
            return;
        }

        //开启线程启动滚动条
        Task copyWorker = createWorker(text,path,fileName,spd,pit,vol,type,simplifiedflg,traditionalflg);
        progressBar.progressProperty().unbind();
        progressBar.progressProperty().bind(copyWorker.progressProperty());
        copyWorker.messageProperty().addListener(new ChangeListener<String>() {
            public void changed(ObservableValue<? extends String> observable, String oldValue,
                                String newValue) {
                System.out.println(newValue);
            }
        });
        new Thread(copyWorker).start();
    }

    @FXML
    public void filePathHandle() {

        Stage fileStage = null;//new Stage();
        DirectoryChooser folderChooser = new DirectoryChooser();

        //fileStage.getIcons().add(new javafx.scene.image.Image("icons/icon.png"));

        folderChooser.setTitle("文件保存路径");

        String path;

        try{

            File selectedFile = null;

            if(filePathLab.getText() != null && !filePathLab.getText().trim().isEmpty()){

                selectedFile = new File(filePathLab.getText());
                if(selectedFile.exists()){
                    folderChooser.setInitialDirectory(selectedFile);
                }
            }


            selectedFile = folderChooser.showDialog(fileStage);
            if(selectedFile == null){
                filePathLab.setText("");
                return;
            }
            path=selectedFile.getPath();
            if(path != null){
                filePathLab.setText(path);
            }else{
                filePathLab.setText("");
            }
        }
        catch(HeadlessException head){
            System.out.println("Open File Dialog ERROR!");
        }
    }

    private void updateInHistory(String text,String path,String fileName,int spd,int pit,int vol,VoiceType per,boolean simplifiedFlg,boolean traditionalFlg){

        //开启线程执行
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                //放入操作履历数据库
                //判断是否需要保存
                UserPreference userPreference = ConfigHelper.getUserPreferenceByUserId(Constants.userId);
                if(!(userPreference != null && userPreference.getAutoDelHistory() != null && 0 == userPreference.getAutoSaveHistory())){
                    UserTextHistory history = ConfigHelper.insertHistory(Constants.userId,text,path,fileName,spd,pit,vol,per.getId(),simplifiedFlg?1:0,traditionalFlg?1:0,TimeUtil.getTime());
                    //显示在列表上
                    if(history != null){
                        textId = history.getTextId();
                        VBox temp = getCellVbox(history);
                        ((VBox) historyScrollPane.getContent()).getChildren().add(0,temp);
                    }
                }

                //放入用户偏好数据
                ConfigHelper.insertOrUpdateUserPreference(Constants.userId,path,fileName,spd,pit,vol,per.getId(),simplifiedFlg?1:0,traditionalFlg?1:0);
                //远程数据同步
                TTVActionUtil.insertHistory(Constants.userId,text,path,fileName,spd,pit,vol,per.getId(),simplifiedFlg?1:0,traditionalFlg?1:0);


            }
        });
    }
    @FXML
    private void getFontCount(){
        String value = setTextTxt.getText();
        value = value.replaceAll(" ","");
        value = value.replaceAll("　","");
        value = value.replaceAll("[\\pP‘’“”]", "");
        value = StringUtil.replaceBlank(value);

        fontCountLab.setText(value.length() + "");

    }

    @FXML
    private void delHistoryHandle(){

        ConfigHelper.deleteHistoryByUserId(Constants.userId);
        ((VBox) historyScrollPane.getContent()).getChildren().clear();

        delMap.clear();
        lookMap.clear();
        textId = null;
    }

    private void checkAuth(){
        JSONObject jsonObject = TTVActionUtil.checkAuth();
        if("0000".equals(jsonObject.get("STATUS"))){
            Constants.token = jsonObject.getString("token");
            return ;
            //token失效重新登录
        }else if("0501".equals(jsonObject.get("STATUS"))){

            throw new BizException(jsonObject.get("MESSAGE").toString());
            //会员过期进行充值
        }else if("0502".equals(jsonObject.get("STATUS"))){

            throw new BizException(jsonObject.get("MESSAGE").toString());
        }else{
            throw new BizException(jsonObject.get("MESSAGE").toString());
        }
    }

    @FXML
    public void begianFindImgHandle() {

        String text = setTextTxt.getText();
        if(text == null || text.trim().isEmpty()){
            AlertUtil.showErrorAlert("请输入分词文本");
            return;
        }

        setSegmentationList();
        //文本处理
        FindImgSegmentationController controller = (FindImgSegmentationController) loadFXMLPage("自动寻词-分词", FXMLPage.FindImgSegmentation, false);
        controller.setMainUIController(this);
        controller.showDialogStage();
    }
    private void  setSegmentationList(){

        segmentationList = new ArrayList<>();

        String[] textArr = setTextTxt.getText().trim().replace(" ", "").split("\n");
        for (int i = 0; i < textArr.length; i++) {
            if(!StringUtil.isNullOrEmpty(textArr[i])){
                List<Word> list = WordSegmenter.segWithStopWords(textArr[i], SegmentationAlgorithm.FullSegmentation);
                segmentationList.add(list);
            }

        }
    }

    public List<List<Word>> getSegmentationList(){
        return this.segmentationList;
    }
}
